package org.particles.gui.statistic;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;

import javax.swing.Action;
import javax.swing.BorderFactory;
import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JRadioButton;

import org.particles.domain.Statistic;
import org.particles.domain.StatisticItem;

/**
 * shows statistic of a parameter. how average, min. and max.
 * values are changing in the time.
 */
public class StatisticPanel extends JPanel {
	private class RadioButtonListener implements ActionListener {
		private final int statType;
		/**
		 * @param statisticType one of values 
		 * StatisticItem.STAT_AVG | StatisticItem.STAT_MIN | StatisticItem.STAT_MAX.
		 */
		public RadioButtonListener(final int statisticType) {
			statType = statisticType;
		}
		@Override
		public void actionPerformed(ActionEvent e) {
			statistic.writeStatistic(statType, statValues);
			selectedStatType = statType;
			diagramPanel.repaint();
		}
	};
	private static final long serialVersionUID = -172931270662519468L;
	private DiagramPanel diagramPanel = new DiagramPanel();
	private List<Double> statValues;
	private Statistic statistic;
	private int selectedStatType = StatisticItem.STAT_AVG;
	private JButton updateStatButton = new JButton();
	
	/**
	 * @param statisticName name that will be appear in header next to radio buttons.
	 */
	public StatisticPanel(final Statistic statistic) {
		this.statistic = statistic;
		statValues = new ArrayList<Double>(statistic.getHistorySize());
		diagramPanel.setStatistic(statValues);
		
		// create radio buttons
		final JRadioButton rbAvg = new JRadioButton();
		rbAvg.setToolTipText("average");
		rbAvg.addActionListener(new RadioButtonListener(StatisticItem.STAT_AVG));
		rbAvg.setSelected(true);
		final JRadioButton rbMin = new JRadioButton();
		rbMin.setToolTipText("min");
		rbMin.addActionListener(new RadioButtonListener(StatisticItem.STAT_MIN));
		final JRadioButton rbMax = new JRadioButton();
		rbMax.setToolTipText("max");
		rbMax.addActionListener(new RadioButtonListener(StatisticItem.STAT_MAX));
		final ButtonGroup group = new ButtonGroup();
		group.add(rbAvg);
		group.add(rbMin);
		group.add(rbMax);
		
		// create header with radio buttons and statistic name.
		final JPanel headerPanel = new JPanel();
		GridBagLayout layout = new GridBagLayout();
		headerPanel.setLayout(layout);
		headerPanel.add(rbAvg, createHeaderCnstr(0));
		headerPanel.add(rbMin, createHeaderCnstr(1));
		headerPanel.add(rbMax, createHeaderCnstr(2));
		GridBagConstraints cnstr = createHeaderCnstr(3);
		cnstr.insets = new Insets(0, 0, 0, 3);
		headerPanel.add(updateStatButton, cnstr);
		final JLabel label = new JLabel(statistic.getName());
		cnstr = createHeaderCnstr(4);
		cnstr.gridwidth = GridBagConstraints.REMAINDER;
		cnstr.weightx = 1;
		cnstr.fill = GridBagConstraints.HORIZONTAL;
		headerPanel.add(label, cnstr);
		
		// add diagram and header panel to this panel
		layout = new GridBagLayout();
		setLayout(layout);
		add(headerPanel, createMainCnstr(0));
		cnstr = createMainCnstr(1);
		cnstr.gridheight = GridBagConstraints.REMAINDER;
		cnstr.weighty = 1;
		cnstr.fill = GridBagConstraints.BOTH;
		add(this.diagramPanel, cnstr);
		
		setBorder(BorderFactory.createLineBorder(Color.GRAY));
		this.diagramPanel.setBorder(BorderFactory.createLineBorder(Color.LIGHT_GRAY));
		setPreferredSize(new Dimension(200, 150));
	}
	
	public void repaintStatistic() {
		statistic.writeStatistic(selectedStatType, statValues);
		diagramPanel.repaint();
	}
	
	/**
	 * sets action for button that updates statistic.
	 */
	public void setUpdateStatAction(final Action action) {
		updateStatButton.setAction(action);
		updateStatButton.setText(null);
		updateStatButton.setMargin(new Insets(0, 0, 0, 0));
		updateStatButton.setSize(24, 24);
	}

	private GridBagConstraints createHeaderCnstr(final int gridx) {
		GridBagConstraints layoutConstraints = new GridBagConstraints();
		layoutConstraints.gridy = 0;
		layoutConstraints.gridx = gridx;
		layoutConstraints.anchor = GridBagConstraints.WEST;
		return layoutConstraints;
	}
	
	private GridBagConstraints createMainCnstr(final int gridy) {
		GridBagConstraints layoutConstraints = new GridBagConstraints();
		layoutConstraints.gridy = gridy;
		layoutConstraints.gridx = 0;
		layoutConstraints.anchor = GridBagConstraints.WEST;
		layoutConstraints.gridwidth = GridBagConstraints.REMAINDER;
		layoutConstraints.weightx = 1;
		return layoutConstraints;
	}
	
}
